/**
 * @file PES.h
 *
 * This file implements the PES parsing.
 *
 * @author Luc Fourestier
 * @date 2009
 */

#ifndef PES_H_
#define PES_H_

#include "TS.h"

#define program_stream_map 188
#define padding_stream 190
#define private_stream_2 191
#define ECM 240
#define EMM 241
#define program_stream_directory 255
#define DSMCC_stream 242
#define ITU_E_stream 248

/**
 * The packet header
 */
typedef struct pack_header_s
{
	unsigned char header[50]; // To be implemented
} pack_header_t;

/**
 * The PES packet
 */
typedef struct PES_s
{
	unsigned long long packet_start_code_prefix;
	unsigned char stream_id;
	unsigned short PES_packet_length;

//	if (stream_id != program_stream_map
//	&& stream_id != padding_stream
//	&& stream_id != private_stream_2
//	&& stream_id != ECM
//	&& stream_id != EMM
//	&& stream_id != program_stream_directory
//	&& stream_id != DSMCC_stream
//	&& stream_id != ITU-T Rec. H.222.1 type E stream)
	unsigned char tag_10;
	unsigned char PES_scrambling_control;
	unsigned char PES_priority;
	unsigned char data_alignment_indicator;
	unsigned char copyright;
	unsigned char original_or_copy;
	unsigned char PTS_DTS_flags;
	unsigned char ESCR_flag;
	unsigned char ES_rate_flag;
	unsigned char DSM_trick_mode_flag;
	unsigned char additional_copy_info_flag;
	unsigned char PES_CRC_flag;
	unsigned char PES_extension_flag;
	unsigned char PES_header_data_length;

//	if (PTS_DTS_flags)
	unsigned long long PTS;
	unsigned long long DTS;

//	if (ESCR_flag = = '1')
	unsigned long long ESCR_base;
	unsigned short ESCR_extension;

//	if (ES_rate_flag = = '1')
	unsigned long long ES_rate;

//	if (DSM_trick_mode_flag = = '1')
	unsigned char trick_mode_control;
	unsigned char field_id;
	unsigned char intra_slice_refresh;
	unsigned char frequency_truncation;
	unsigned char rep_cntrl;


//	if ( additional_copy_info_flag = = '1')
	unsigned char additional_copy_info;

//	if ( PES_CRC_flag = = '1')
	unsigned short previous_PES_packet_CRC;

//	if ( PES_extension_flag = = '1')
	unsigned char PES_private_data_flag;
	unsigned char pack_header_field_flag;
	unsigned char program_packet_sequence_counter_flag;
	unsigned char P_STD_buffer_flag;
	unsigned char PES_extension_flag_2;

//	if ( PES_private_data_flag = = '1')
	unsigned char PES_private_data[16];

//	if (pack_header_field_flag = = '1')
	unsigned char pack_field_length;
	pack_header_t pack_header;

//	if (program_packet_sequence_counter_flag = = '1')
	unsigned char program_packet_sequence_counter;
	unsigned char MPEG1_MPEG2_identifier;
	unsigned char original_stuff_length;

//	if ( P-STD_buffer_flag = = '1')
	unsigned char tag_01;
	unsigned char P_STD_buffer_scale;
	unsigned short P_STD_buffer_size;

//	if ( PES_extension_flag_2 = = '1')
	unsigned char PES_extension_field_length;

	unsigned char PES_packet_data_byte[TS_SIZE];
	unsigned char PES_packet_data_byte_length;
} PES_t;

/**
 * @brief Fill the PES
 */
int PES_Create(unsigned char * Buffer, unsigned int *Size, PES_t * PES);

#endif /* PES_H_ */
